package cn.com.sinux.spring.utils.image;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.image.BufferedImage;
import java.io.File;

/**
 * .
 * <p/>
 *
 * @author <a href="mailto:oznyang@163.com">oznyang</a>
 * @version V1.0, 2009-5-8 14:11:27
 */
public class MagickCommandImageTransform implements ImageTransform {

    private final static Logger logger = LoggerFactory.getLogger(MagickCommandImageTransform.class);
    private String srcFilePath;
    private static boolean isWindows = System.getProperty("os.name").toLowerCase().indexOf("windows") > -1;

    private StringBuffer cmdBuf = new StringBuffer();

    public boolean load(BufferedImage bufferedImage, String srcFilePath) {
        if (srcFilePath == null) {
            logger.warn("Source file path is null!");
            return false;
        }
        File file = new File(srcFilePath);
        if (!(file.exists() && file.isFile())) {
            logger.error("file '{}' is not exists or cannot read.", srcFilePath);
            return false;
        }
        this.srcFilePath = srcFilePath;
        return true;
    }

    public boolean load(String srcFilePath) {
        if (srcFilePath == null) {
            logger.warn("Source file path is null!");
            return false;
        }
        File file = new File(srcFilePath);
        if (!(file.exists() && file.isFile())) {
            logger.error("file '{}' is not exists or cannot read.", srcFilePath);
            return false;
        }
        this.srcFilePath = srcFilePath;
        return true;
    }

    public boolean save(String destFilePath) {
        StringBuffer cmd = new StringBuffer();
        if (isWindows)
            cmd.append("cmd /c ");
        cmd.append("convert ");
        cmd.append(cmdBuf.toString());
        cmd.append(srcFilePath);
        if (srcFilePath.toLowerCase().endsWith(".gif")) {
            cmd.append("[0]");
        }
        cmd.append(" ").append(destFilePath);
        logger.debug("Magick Command:{}", cmd);
        try {
            String cmdStr = cmd.toString();
            Process proc = Runtime.getRuntime().exec(cmdStr);
            int exitVal = proc.waitFor();
            if (exitVal != 0)
                return false;
        } catch (Exception e) {
            logger.error("Error exec magick convert command [" + cmd + "]", e);
        }
        return true;
    }

    public void resize(int width, int height) throws Exception {
        if (width <= 0 && height <= 0)
            return;

        int destWidth = width < 0 ? 0 : width;
        int destHeight = height < 0 ? 0 : height;

        cmdBuf.append(" -resize ");
        if (destWidth > 0) cmdBuf.append(destWidth);
        cmdBuf.append("x");
        if (destHeight > 0) cmdBuf.append(destHeight);
        cmdBuf.append(" ");

    }

    public void rotate(double rotate) throws Exception {
        cmdBuf.append(" -rotate ").append(rotate).append(" ");
    }

    public void resizeWithMaxWidth(int maxWidth) throws Exception {
        if (maxWidth <= 0)
            return;

        cmdBuf.append(" -resize ");
        cmdBuf.append(maxWidth);
        cmdBuf.append("x> ");
    }

    public void rotateWithMaxWidth(double rotate, int maxWidth) throws Exception {
        cmdBuf.append(" -rotate ").append(rotate).append(" ");

        if (maxWidth > 0) {
            cmdBuf.append(" -resize ");
            cmdBuf.append(maxWidth);
            cmdBuf.append("x> ");
        }

    }

    /**
     * 以像素为单位截取图像.
     *
     * @param left   左坐标.
     * @param top    顶坐标.
     * @param width  宽度.
     * @param height 高度.
     */
    public void crop(final int left, final int top, final int width, final int height) {
        cmdBuf.append(" -crop ").append(width).append("x").append(height).append("+").append(left).append("+").append(top).append(" ");
    }
}
